; These routines use the UVALUE of the first child of the compound
; widget base. Hence, the compound widget should not make use
; of this UVALUE or confusion will result.
;
; One solution to this problem is to include an extra base
; between the top base and the rest of the widgets. For example:
;
; OUTER_BASE = WIDGET_BASE()
; INNER_BASE = WIDGET_BASE(OUTER_BASE)
; OTHER_WIDGET = WIDGET_BUTTON(INNER_BASE)
; ...
;
; PROCEDURE:
; Every compound widget that uses these procedures keeps the
; most recently accessed state in the UVALUE of the first child
; of the compound widget base. These procedures load and unload
; the states for each instance of compound widget as needed.
;
; EXAMPLE:
;
; Here is the framework for a compound widget at its event function
;
; function CW_XYZ_EVENT, ev
;
; COMMON CW_XYZ_BLK, state_base, state_stash, state
; CW_LOADSTATE, ev.handler, state_base, state_stash, state
;
; ; Event processing goes here. The widget state is
; ; contained in the variable state.
; end
;
; function CW_XYZ, parent
;
; COMMON CW_XYZ_BLK, state_base, state_stash, state
; ;
; base = widget_base()
;
; ; Other widgets are created here
;
; new_state = ... ; The new state is widget dependent
;
; CW_SAVESTATE, base, state_base, new_state
; return, base
; end
;
; MODIFICATION HISTORY:
; AB, June 1992
;-
pro CW_SAVESTATE, base, state_base, new_state
; Load the new_state variable into the user value of the first child
; of base.
COMMON CW_SAVSTAT_OBS, obsolete
if not KEYWORD_SET(obsolete) then begin
obsolete = 1
message,/INFO,"The CW_SAVESTATE and CW_LOADSTATE user library routines are obsolete. They are superceeded by the NO_COPY keyword to the WIDGET_CONTROL procedure."
endif
; There are many reasons why we might want to invalidate the cache
; by setting state_base to zero. The logic can get a bit tricky.
;
; - state_base is undefined, meaning that this is the first
; savestate for this compound widget class.
;
; - state_base is the same as our new widget, meaning that
; the state in the common block is for a previous incarnation
; of a widget of this class headed by a widget with the
; same ID. (A very rare case)
;
; - state_base is an invalid ID, meaning the widget owning
; the current state has died and not been reused. (This is likely)
;
; - state_base is valid, but has a different event handler than
; the new ID. In this case, the widget owning the current state
; has died and has been since reused, but in a different
; application. The assumption here is that two widgets
; with non-null event handlers that agree must be different
; instantiations of the same class. (This is likely)
;
; Note: IDL's IF statement does not do short circuit evaluation, hence
; the strange looking structure of this code.
if (n_elements(state_base) eq 0) then begin
state_base=0L
endif else if (base eq state_base) then begin
state_base = 0L
endif else if (not widget_info(state_base, /VALID)) then begin
state_base = 0L
endif else if (widget_info(base, /EVENT_FUNC) $
ne widget_info(state_base, /EVENT_FUNC)) then begin